package com.higgins.eventtracking.client.health.toplevel;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TabBar;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.higgins.eventtracking.client.DietTrackingService;
import com.higgins.eventtracking.client.DietTrackingServiceAsync;
import com.higgins.eventtracking.client.EventTrackingService;
import com.higgins.eventtracking.client.EventTrackingServiceAsync;
import com.higgins.eventtracking.client.FinanceTrackingService;
import com.higgins.eventtracking.client.FinanceTrackingServiceAsync;
import com.higgins.eventtracking.client.dto.HealthAlertDTO;
import com.higgins.eventtracking.client.dto.RuleDTO;
import com.higgins.eventtracking.client.health.components.GenericChartPanel;
import com.higgins.eventtracking.client.health.components.GenericStatsTabParent;
import com.higgins.eventtracking.client.health.components.GenericTabInterface;
import com.higgins.eventtracking.client.health.components.HealthOverviewChart;
import com.higgins.eventtracking.client.health.components.HealthOverviewChartListBox;
import com.higgins.eventtracking.client.health.fundamentals.AchievementTab;
import com.higgins.eventtracking.client.health.fundamentals.DigestionTab;
import com.higgins.eventtracking.client.health.fundamentals.FrameOfMindTab;
import com.higgins.eventtracking.client.health.fundamentals.GoalsSubTab;
import com.higgins.eventtracking.client.health.fundamentals.GoalsTab;
import com.higgins.eventtracking.client.health.fundamentals.HourlyTab;
import com.higgins.eventtracking.client.health.fundamentals.HygieneTab;
import com.higgins.eventtracking.client.health.fundamentals.NegativeTab;
import com.higgins.eventtracking.client.health.fundamentals.SupportTab;
import com.higgins.eventtracking.client.health.fundamentals.TimetableTab;
import com.higgins.eventtracking.client.health.fundamentals.WellBeingTab;

public class TopLevelTab extends VerticalPanel	implements GenericTabInterface		{
	private final EventTrackingServiceAsync eventTrackingService = GWT
		.create(EventTrackingService.class);
	private final DietTrackingServiceAsync dietTrackingService = GWT
	    .create(DietTrackingService.class);
    private final EventTrackingServiceAsync greetingService = GWT
        .create(EventTrackingService.class);
	private GenericStatsTabParent parent = null;
	private boolean firstRun = true;
	private Integer tabIndex = null;
	private String tabTitle = null;
    private int maxRow = 6;
    private int maxColumn = 3;
    private Integer width = 300;
    private Integer height = 20;
    private List<List<Widget>> labelRows = new ArrayList<List<Widget>>();
    private GoalsTab goalsTab = null;
//    private Label waterToday;
//    private Label numberOfBrushes;
//    private Label lastBrushed;
//	private TabPanel tabPanel = null;
//	private GoalsSubTab goalsSubTab = null;
	
	@Override
	public Integer getTabIndex() {
		return tabIndex;
	}
	@Override
	public void setTabIndex(Integer index) {
		this.tabIndex = index;
	}
	@Override
	public String getTabTitle()	{
		return tabTitle;
	}
	@Override
	public void setTabTitle(String tabTitle)	{
		this.tabTitle = tabTitle;
	}

	public TopLevelTab(GenericStatsTabParent parent)	{	
		this.parent = parent;
	}
	
	public void update()	{
		if (firstRun)	
			initialise();
	}
	private void initialise()	{
		populateTabPanel();
		firstRun = false;
	}
	public void populateTabPanel()	{
	    createCells();
		populateTopSection();
		goalsTab = new GoalsTab("TopLevelType");
		add(goalsTab);
		goalsTab.update();
//		checkFrameOfMindAndPopulateGoalsTab();
	}
	
	private void checkFrameOfMindAndPopulateGoalsTab()	{
		eventTrackingService.retrieveRecommendedFrameOfMind(new AsyncCallback<String>() {

			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(String result) {
//				populateGoalsTab(result);
			}
			
		});
	}
	
	private HealthAlertDTO getNoBrushesDTO(boolean count) {
        HealthAlertDTO dto = new HealthAlertDTO();
        dto.setName("Brushes Today");
        dto.setEventType("HealthEvent");
        dto.setEventName("Brush Teeth");
        dto.setHealthEvent("Brush Teeth");
        dto.setTimePeriod("Hours");
        dto.setCount(count);
        return dto;
	}

   private HealthAlertDTO getEatenDTO(boolean count) {
        HealthAlertDTO dto = new HealthAlertDTO();
        dto.setName("Eaten");
        dto.setEventType("ConsumptionEvent");
        dto.setEventName("Eaten");
        dto.setHealthEvent("Eaten");
        dto.setTimePeriod("Hours");
        dto.setCount(count);
        return dto;
    }

   private HealthAlertDTO getWaterDTO(boolean count) {
       HealthAlertDTO dto = new HealthAlertDTO();
       dto.setName("Fluids");
       dto.setEventType("ConsumptionEvent");
       dto.setEventName("Water");
       dto.setHealthEvent("Water");
       dto.setTimePeriod("Hours");
       dto.setCount(count);
       return dto;
   }


	

	   private void populateTopSection()   {
	       int rowIndex = 0;
	       int columnIndex = 0;
           setText(rowIndex++, columnIndex, "1. Fuel - (" + getMealType() + ")", 180);
           setText(rowIndex++, columnIndex, "2. Planning", 180);
           setText(rowIndex++, columnIndex, "3. Complete Goals", 180);
           setText(rowIndex++, columnIndex, " ", 180);
           setText(rowIndex++, columnIndex, " ", 180);
           setText(rowIndex++, columnIndex, " ", 180);

           dietTrackingService.retrieveWaterToday(waterCallback);        
           dietTrackingService.retrieveCaloriesToday(caloriesCallback);        
           greetingService.retrievePeriodSinceAlert(getNoBrushesDTO(true), numberOfBrushesCallback);
           greetingService.retrievePeriodSinceAlert(getNoBrushesDTO(false), lastBrushedCallback);
           greetingService.retrievePeriodSinceAlert(getEatenDTO(false), lastEatenCallback);
           greetingService.retrievePeriodSinceAlert(getWaterDTO(false), lastWaterCallback);

//           String frameOfMind = "Relationship";
           dietTrackingService.hasEaten(3, new AsyncCallback<Boolean>() {
                @Override
                public void onFailure(Throwable caught) {
                }
                @Override
                public void onSuccess(Boolean result) {
                    if (!result) {
                        greetingService.retrieveRules("MealType", getMealType(), mealCallback);     
                    }
                }
           });
           greetingService.getWellBeing(new AsyncCallback<Integer>() {
                @Override
                public void onFailure(Throwable caught) {
                }
                @Override
                public void onSuccess(Integer result) {
                    String frameOfMind = "Depressed";
                    if (result <= 4)    {
                        greetingService.retrieveRules("FrameOfMindType", frameOfMind, depressedCallback);     
                    }
                } });
	    }

	   private String getMealType()    {
           String[] dateParts = DateTimeFormat.getFormat( "HH:mm:ss" ).format( new Date() ).split( ":");
           String hourStr = dateParts[0];
           int hour = Integer.valueOf(hourStr);
           if (hour < 11)   {
               return "Breakfast";
           } else if (hour < 15) {
               return "Lunch";
           } else {
               return "Dinner";
           }
	   }
	

	private void createCells() {
        List<Widget> labelRow = new ArrayList<Widget>();
        if (maxRow<3)   {
            maxRow = 3;
        }
        for (int rowIndex = 0; rowIndex <= maxRow; rowIndex++)  {
            HorizontalPanel rowPanel = new HorizontalPanel();
            rowPanel.setSpacing(0);
            for (int columnIndex = 0;columnIndex <= maxColumn; columnIndex++)   {
                Label label = new Label();
                label.setWidth(width+"px");
                //
                label.setHeight(height + "px");
                labelRow.add(label);

                rowPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
                rowPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
                rowPanel.setHeight(height+"px");
                rowPanel.add(label);
                rowPanel.setCellHeight(label, "0px");
            }
            add(rowPanel);
            labelRows.add(labelRow);
            labelRow = new ArrayList<Widget>();
        }
	    
	}
	
//    private void populateTopSection()   {
//        
//        Label label1 = new Label("1. Fuel");
//        label1.getElement().getStyle().setFontWeight(FontWeight.BOLD);
//
//        Label label2 = new Label("2. Planning");
//        label2.getElement().getStyle().setFontWeight(FontWeight.BOLD);
//
//        Label label3 = new Label("3. Complete Goals");
//        label3.getElement().getStyle().setFontWeight(FontWeight.BOLD);
//
//        add(label1);
//        add(label2);
//        add(label3);
//        
//        VerticalPanel spacer = new VerticalPanel();
//        spacer.setHeight("5em");
//        add(spacer);
//    }
  	
//	private void populateGoalsTab(String subTabTitle)	{
//		tabPanel = new TabPanel();
//		goalsSubTab = new GoalsSubTab(subTabTitle);
//		goalsSubTab.update();
//		tabPanel.add(goalsSubTab, subTabTitle);
//		tabPanel.setHeight("20em");
//		tabPanel.setWidth("30em");
//		add(tabPanel);
//		tabPanel.selectTab(0);
//	}

    private void setText(int rowIndex, int columnIndex, String result)   {
        setText(rowIndex, columnIndex, result, width);
    }
    private void setText(int rowIndex, int columnIndex, String result, int width)   {
        int maxWidth = 37;

        List<Widget> labelRow = labelRows.get(rowIndex);
        Label label = (Label)labelRow.get(columnIndex);
        label.setWidth(width+"px");
        label.setText(result.length()>maxWidth?result.substring(0, maxWidth):result);
        label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
    }
	
	
	@Override
	public void addChartPanel(GenericChartPanel chartPanel) {
		// TODO Auto-generated method stub
	}
	
	
	
	
	
	
	
	
	
	//
	// CALLBACKS
	//
	
	private AsyncCallback<Double> waterCallback = new AsyncCallback<Double>() {
        private int rowIndex = 0;
        private int columnIndex = 3;
        
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Water Today");
        }

        public void onSuccess(Double result) {
            setText("Water: " + result+ "    (" + Math.round(100*result/2000) + " % of 2,000)");
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };
    
    private AsyncCallback<Double> caloriesCallback = new AsyncCallback<Double>() {
        private int rowIndex = 1;
        private int columnIndex = 3;
        
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Water Today");
        }

        public void onSuccess(Double result) {
            setText("Calories: " + result + "   (" + Math.round(100*result/3000) + " % of 3,000)");
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };
    
    
	
    private AsyncCallback<HealthAlertDTO> numberOfBrushesCallback = new AsyncCallback<HealthAlertDTO>() {
        private int rowIndex = 2;
        private int columnIndex = 3;
        
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve No Brushes");
        }

        public void onSuccess(HealthAlertDTO dto) {
            if (dto.getCount())     {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getName());
            } else {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getTimePeriod() + " since last " + dto.getEventName());
            }
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };    
       
    private AsyncCallback<HealthAlertDTO> lastBrushedCallback = new AsyncCallback<HealthAlertDTO>() {
        private int rowIndex = 3;
        private int columnIndex = 3;
                
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Last Brushed");
        }

        public void onSuccess(HealthAlertDTO dto) {
            if (dto.getCount())     {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getName());
            } else {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getTimePeriod() + " since last " + dto.getEventName());
            }
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };        
    
    private AsyncCallback<HealthAlertDTO> lastEatenCallback = new AsyncCallback<HealthAlertDTO>() {
        private int rowIndex = 4;
        private int columnIndex = 3;
                
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Last Eaten");
        }

        public void onSuccess(HealthAlertDTO dto) {
            if (dto.getCount())     {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getName());
            } else {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getTimePeriod() + " since last " + dto.getEventName());
            }
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };        
    
    private AsyncCallback<HealthAlertDTO> lastWaterCallback = new AsyncCallback<HealthAlertDTO>() {
        private int rowIndex = 5;
        private int columnIndex = 3;
                
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Last Eaten");
        }

        public void onSuccess(HealthAlertDTO dto) {
            if (dto.getCount())     {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getName());
            } else {
                setText(dto.getNumberOfPeriodsToDate() + " " + dto.getTimePeriod() + " since last " + dto.getEventName());
            }
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };        
        
    
    
    // 
    // 
    // 
    private AsyncCallback<List<RuleDTO>> mealCallback = new AsyncCallback<List<RuleDTO>>() {
        private int rowIndex = 0;
        private int columnIndex = 1;
        
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Depressed List");
        }

        @Override
        public void onSuccess(List<RuleDTO> result) {
            for (RuleDTO dto:result) {
                if (rowIndex < maxRow)   {
                    setText(dto.getTask());
                    rowIndex++;
                }
            }
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>width?result.substring(0, width):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };        
    
    private AsyncCallback<List<RuleDTO>> depressedCallback = new AsyncCallback<List<RuleDTO>>() {
        private int rowIndex = 0;
        private int columnIndex = 2;
        
        public void onFailure(Throwable caught) {
            setText("Unable to retrieve Depressed List");
        }

        @Override
        public void onSuccess(List<RuleDTO> result) {
            for (RuleDTO dto:result) {
                if (rowIndex < maxRow)   {
                    setText(dto.getTask());
                    rowIndex++;
                }
            }
        }
        private void setText(String result)   {
            int width = 37;
            List<Widget> labelRow = labelRows.get(rowIndex);
            Label label = (Label)labelRow.get(columnIndex);
            label.setText(result.length()>37?result.substring(0, 37):result);
            label.getElement().getStyle().setFontWeight(FontWeight.BOLD);
        }
    };   

    
}
